#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include "gprs.h"
#include "sql.h"
#include "global_val.h"

static int gprs_uart_fd;

/*********************************************************************
 * @fn      serial_init
 *
 * @brief   串口初始化设置，波特率、流控制、停止位数、数据位、校验位
 *
 * @param   fd,串口设备文件的文件描述符
 *
 * @return  none
 */
void gprs_serial_init(int fd)
{
	struct termios options;
	tcgetattr(fd, &options);

	options.c_cflag |= ( CLOCAL | CREAD );
	options.c_cflag &= ~PARENB;
	options.c_iflag &= ~INPCK;

	options.c_cflag &= ~CSIZE;
	options.c_cflag &= ~CRTSCTS;

	options.c_cflag |= CS8;
	options.c_cflag &= ~CSTOPB;
	options.c_iflag |= IGNPAR;
	options.c_iflag &= ~(ICRNL | IXON);

	options.c_oflag &= ~OPOST;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

	cfsetispeed(&options, B115200);
	cfsetospeed(&options, B115200);
	tcsetattr(fd,TCSANOW,&options);
}

/*********************************************************************
 * @fn      usart_setup
 *
 * @brief   串口初始化函数
 *
 * @param   none
 *
 * @return  none
 */
void gprs_usart_setup(const unsigned char *uart_root)
{
	//O_NONBLOCK设置为非阻塞模式，在read时不会阻塞住，在读的时候将read放在while循环中
	gprs_uart_fd=open(uart_root, O_RDWR | O_NOCTTY | O_NONBLOCK);
	gprs_serial_init(gprs_uart_fd);
	tcflush(gprs_uart_fd, TCIOFLUSH);//清空输入输出缓冲区
}

/*********************************************************************
 * @fn      gprs_read_line
 *
 * @brief   读取传入输入流中的一行数据 判断其数据格式
 *
 * @param   stream:文件输入流
 *
 * @return  成功返回1，失败返回0
 */
int gprs_read_line(FILE *stream)
{
	char replay[128];
	int res=0;
	char *fgets_res;
	time_t timing;
	
	timing = time(NULL)+5;
	while(time(NULL)<timing)
	{
		fgets_res = fgets(replay, sizeof(replay), stream);
		
		if(fgets_res!=NULL)
		{
			printf("gets:%s", replay);
		}
		
		//回复error
		if(fgets_res!=NULL&&strstr(replay, "ERROR")!=NULL)
		{
			break;
		}
		
		//回复OK
		if(fgets_res!=NULL&&strstr(replay, "OK")!=NULL)
		{
			res = 1;
			break;
		}		
	}
	
	return res;
}

/*********************************************************************
 * @fn      gprs_read_char
 *
 * @brief   读取传入输入流中的一个字节数据 判断其数据格式
 *
 * @param   stream:文件输入流
 *
 * @return  成功返回1，失败返回0
 */
int gprs_read_char(FILE *stream)
{
	char c;
	int res=0;
	time_t timing;
	
	timing = time(NULL)+5;
	while(time(NULL)<timing)
	{
		c = getc(stream);
		
		if(c!=EOF)
		{
			//printf("getc:%c\n", c);
		}
		
		if(c!=EOF&&c=='>')
		{
			res = 1;
			break;
		}
	}
	
	return res;
}

/*********************************************************************
 * @fn      reverse_phone_number
 *
 * @brief   将电话号码转化为对应的格式，两位翻转一次 
 *
 * @param   number:电话号码 字节长度必须大于等于13
 *
 * @return  成功返回1，失败返回0
 */
int reverse_phone_number(char *number)
{
	int res=0;
	int i;
	char swap;
	
	//0 2 4 6 8 10
	if(strlen(number)==11)
	{
		for(i=0; i<10; i=i+2)
		{
			swap   = number[i];
			number[i]   = number[i+1];
			number[i+1] = swap;
		}
		
		number[i+1] = number[i];
		number[i]   = 'F';
		number[i+2] = '\0';
		res         = 1;
	}
	
	return res;
}

/*********************************************************************
 * @fn      gprs_send
 *
 * @brief   发送给对应的号码指定的短信消息  message为已转成unicode
 *
 * @param   number:电话号码 字节长度必须大于等于13
 *
 * @return  成功返回1，失败返回0
 */
int gprs_send(int fd, char *phonenumber, const char *message)//发送函数，用于AT指令的发送
{
	int nwrite,len,res=1;
	char buff[128];
	FILE *fd_stream = fdopen(fd, "r+");
	
	nwrite = write(fd, "AT\r\n", strlen("AT\r\n"));
	res    = gprs_read_line(fd_stream);
	if(res==0)
		return res;
	
	nwrite = write(fd, "AT+CMGF=0\r\n", strlen("AT+CMGF=0\r\n"));
	res    = gprs_read_line(fd_stream);	
	if(res==0)
		return res;

	len = strlen(message)/2;
	sprintf(buff, "AT+CMGS=%d\r", 15+len);
	nwrite = write(fd, buff, strlen(buff));
	res    = gprs_read_char(fd_stream);
	if(res==0)
		return res;
	
	res = reverse_phone_number(phonenumber);
	if(res==0)
		return res;
	
	//000800 正常 001800 0级别
	sprintf(buff, "0011000D9168%s000800%02x%s", phonenumber, len, message);
	strcat(buff,"\x1a");//ctrl+z 的ASC 值26
	nwrite = write(fd, buff, strlen(buff));
	res    = gprs_read_line(fd_stream);
	if(res==0)
		return res;
	
	//fclose(fd_stream);
	
	return res;
}

/*********************************************************************
 * @fn      gprs_send_message_to_emergency_call
 *
 * @brief   从数据库中读取号码进行信息发送  message为已转成unicode
 *
 * @param   message：发送的消息
 *
 * @return  成功返回0，失败返回-1
 */
int gprs_send_message_to_emergency_call(char *message)
{
	char *emergency_call_table = "emergency_call_number";
	char buf[10][10][256];//最大 10行10列
	int col[]={1};//ID  电话号码
	char type[]={SQL_FIEL_TYPE_STR};
	int num,i,res;
	
	num = sql_get_table_nfield(emergency_call_table, col, type, 1, buf);
	if(num==-1)
	{
		printf("gprs_send fail\n");
		return -1;
	}
	
	for(i=0; i<num; ++i)
	{
		res = gprs_send(gprs_uart_fd, buf[i][0], message);
		printf("number:%s\n", buf[i][0]);
		if(res==0)
		{
			printf("gprs_send fail\n");
			return -1;
		}
	}
		
	return 0;
}

